package com.party.mem.biz.member;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.party.api.dto.wechat.requst.XcxQrCodeRequest;
import com.party.common.constant.Constant;
import com.party.common.redis.StringJedis;
import com.party.common.utils.DateUtils;
import com.party.common.utils.StringUtils;
import com.party.core.exception.BusinessException;
import com.party.core.model.YesNoStatus;
import com.party.core.model.commune.CUserIntegralMobileOutput;
import com.party.core.model.member.Member;
import com.party.core.model.member.MemberGroup;
import com.party.core.model.member.PartnerMember;
import com.party.core.model.system.RoleType;
import com.party.core.model.system.SysConfig;
import com.party.core.model.system.SysRole;
import com.party.core.model.wechatPlatform.WechatOpenMember;
import com.party.core.service.member.IMemberGroupService;
import com.party.core.service.member.IMemberService;
import com.party.core.service.member.IPartnerMemberService;
import com.party.core.service.picCloud.CosCloudBizService;
import com.party.core.service.system.ISysConfigService;
import com.party.core.service.system.ISysRoleService;
import com.party.core.service.wechatPlatform.impl.WechatOpenMemberService;
import com.party.file.cos.dto.UploadResult;
import com.party.file.cos.meta.InsertOnly;
import com.party.mem.biz.file.FileBizService;
import com.party.mem.utils.excel.ExportExcel;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * @program: party
 * @description: 积分业务
 * @author: Hua Qunhao
 * @create: 2019-11-14 12:11
 **/
@Service
public class CIntegralBizToService {

    private String uploadPath = Constant.UPLOAD_EXCEL;
    private static final String REDIS_LIST_KEY = "export_excel_list";
    Logger logger = LoggerFactory.getLogger(getClass());

    @Autowired
    private ISysConfigService sysConfigService;
    @Autowired
    private IMemberGroupService memberGroupService;
    @Autowired
    private IPartnerMemberService partnerMemberService;
    @Autowired
    private IMemberService memberService;

    @Autowired
    private WechatOpenMemberService wechatOpenMemberService;

    @Autowired
    private FileBizService fileBizService;

    @Autowired
    private ISysRoleService sysRoleService;
    @Autowired
    private CosCloudBizService cosCloudBizService;
    @Autowired
    private StringJedis stringJedis;

    private final static String excel2003L = ".xls";    //2003- 版本的excel
    private final static String excel2007U = ".xlsx";   //2007+ 版本的excel

    /**
     * 描述：根据文件后缀，自适应上传文件的版本
     *
     * @param inStr,fileName
     * @return
     * @throws Exception
     */
    public Workbook getWorkbook(InputStream inStr, String fileName) throws Exception {
        Workbook wb;
        String fileType = fileName.substring(fileName.lastIndexOf("."));
        if (excel2003L.equals(fileType)) {
            wb = new HSSFWorkbook(inStr);  //2003-
        } else if (excel2007U.equals(fileType)) {
            wb = new XSSFWorkbook(inStr);  //2007+
        } else {
            throw new Exception("解析的文件格式有误！");
        }
        return wb;
    }


    /**
     * 导入分社人员
     *
     * @param wb       文件
     * @param fileName 文件名
     * @throws Exception
     */
    public void branchMemberImport(Workbook wb, String fileName, String sessionId) throws Exception {
        //行知公社Id
        String xzgsId = this.getBranchIdByFileName("行知公社");
        //分社id
        String branchId = this.getBranchIdByFileName(fileName);
        try {
            List<List<String>> sheetInfo = this.getSheetInfo(wb);
            for (int k = 0; k < sheetInfo.size(); k++) {
                List<String> rowData = sheetInfo.get(k);
                String name = rowData.get(0); // 人名
                String mobile = rowData.get(1); // 手机号
                try {
                    String memberId = "";
                    List<String> memberIds = memberService.findByMobileOrRealName(mobile, null, Member.MEMBER_PERSONAL);
                    if (memberIds.size() > 0) {
                        memberId = memberIds.get(0);
                    } else {
                        logger.error("用户不存在mobile" + mobile);
                        throw new BusinessException(100, "用户不存在");
                    }
                    logger.info("开始维护机构关系name:" + name + "------mobile:" + mobile);

                    PartnerMember xzgsP = partnerMemberService.findByPartnerAndMember(xzgsId, memberId);
                    PartnerMember branchP = partnerMemberService.findByPartnerAndMember(branchId, memberId);
                    if (xzgsP != null && branchP == null) {//如果在主分社下而且在分社下不存在关系
                        //修改绑定关系
                        xzgsP.setPartnerId(branchId);
                        xzgsP.setPartnerType(YesNoStatus.YES.getCode());
                        partnerMemberService.update(xzgsP);

                        logger.info("修改绑定关系成功name:" + name + "------mobile:" + mobile);
                    } else if (branchP == null) {
                        //绑定新关系
                        PartnerMember newP = new PartnerMember();
                        newP.setPartnerId(branchId);
                        newP.setMemberId(memberId);
                        PartnerMember mainOrg = partnerMemberService.getMainOrg(memberId,xzgsId);
                        if (mainOrg == null) {
                            newP.setPartnerType(YesNoStatus.YES.getCode());
                        }else{
                            newP.setPartnerType(YesNoStatus.NO.getCode());
                        }
                        partnerMemberService.insert(newP);
                        logger.info("绑定新关系成功name:" + name + "------mobile:" + mobile);
                    }
                } catch (BusinessException e) {
                    logger.error("维护用户机构关系异常mobile" + mobile, e);
                    continue;
                } catch (Exception e) {
                    logger.error("维护用户机构关系异常mobile" + mobile, e);
                    continue;
                }
            }
        } catch (Exception e) {
            logger.error("最外层导入人员成绩异常", e);
        }
    }

    /**
     * 获取表格信息
     *
     * @param workbook 文件
     * @return
     * @throws Exception
     */
    private List<List<String>> getSheetInfo(Workbook workbook) throws Exception {
        List<List<String>> rowdatas = Lists.newArrayList();
        Sheet sheet = workbook.getSheetAt(0);
        Row titleRow = sheet.getRow(0);
        //遍历当前sheet中的所有行

        for (int j = 0; j <= sheet.getLastRowNum(); j++) {
            Row row = sheet.getRow(j);
            //遍历所有的列
            List<String> coldatas = Lists.newArrayList();
            for (int y = row.getFirstCellNum(); y < titleRow.getLastCellNum(); y++) {
                //找到某一列中的单元格
                Cell cell = row.getCell(y);
                if (cell != null) {
                    //获取单元格中的值
                    String colValue = getCellValue(cell);
                    coldatas.add(colValue);
                } else {
                    coldatas.add("");
                }
            }
            rowdatas.add(coldatas);
        }
        System.out.println(JSONObject.toJSONString(rowdatas));
        return rowdatas;
    }

    /**
     * 描述：对表格中数值进行格式化
     *
     * @param cell
     * @return
     */
    @SuppressWarnings("JavaDoc")
    private String getCellValue(Cell cell) {
        String value = null;
        DecimalFormat df = new DecimalFormat("0");  //格式化number String字符
        SimpleDateFormat sdf = new SimpleDateFormat("yyy-MM-dd");  //日期格式化
        DecimalFormat df2 = new DecimalFormat("0.00");  //格式化数字

        switch (cell.getCellType()) {
            case Cell.CELL_TYPE_STRING:
                value = cell.getRichStringCellValue().getString();
                break;
            case Cell.CELL_TYPE_NUMERIC:
                if ("General".equals(cell.getCellStyle().getDataFormatString())) {
                    value = df.format(cell.getNumericCellValue());
                } else if ("m/d/yy".equals(cell.getCellStyle().getDataFormatString())) {
                    value = sdf.format(cell.getDateCellValue());
                } else {
                    value = df2.format(cell.getNumericCellValue());
                }
                break;
            case Cell.CELL_TYPE_BOOLEAN:
                value = String.valueOf(cell.getBooleanCellValue());
                break;
            case Cell.CELL_TYPE_BLANK:
                value = "";
                break;
            default:
                break;
        }
        return value;
    }

    /**
     * @Description:通过文件名称获取分社id
     * @Param:filename
     * @return:BranchId
     * @Author: Hua Qunhao
     * @Date: 2019/11/14
     */
    public String getBranchIdByFileName(String fileName) throws Exception {
        String code = "";
        if (fileName.contains("麒麟")) {
            code = "XZGS_QL_ID";
        } else if (fileName.contains("健行")) {
            code = "XZGS_JX_ID";
        } else if (fileName.contains("赢家")) {
            code = "XZGS_YJ_ID";
        } else if (fileName.contains("行知公社")) {
            code = "XZGSID";
        }
        if (StringUtils.isEmpty(code)) {
            throw new BusinessException(fileName + "文件名未找到匹配的code");
        }
        SysConfig xzgsConfig = sysConfigService.findByCode(code);
        if (xzgsConfig == null || StringUtils.isEmpty(xzgsConfig.getValue())) {
            throw new BusinessException(fileName + "未设置账号id");
        }
        MemberGroup memberGroup = memberGroupService.get(xzgsConfig.getValue());
        if (memberGroup == null) {
            throw new BusinessException(fileName + "账号id设置有误");
        }
        return memberGroup.getId();
    }

    /**
     * @Description:生成行知公社小程序二维码
     * @Param: partnerId, pmId
     * @return:a
     * @Author: Hua Qunhao
     * @Date: 2019/11/18
     */
    public void generateXZGSXCXQRCode(String partnerId,String memberId) {
        PartnerMember byPartnerAndMember = partnerMemberService.getMainOrg(memberId, partnerId);
        if(byPartnerAndMember==null){
            logger.error("积分--生成个人资料小程序码异常", "不存在主分社");
        }
        try {
            //生成个人资料小程序码
            WechatOpenMember openMember = wechatOpenMemberService.findByType(Constant.WECHAT_ACCOUNT_TYPE_SYSTEM_XCX_INTEGRAL);
            XcxQrCodeRequest qrCodeRequest = new XcxQrCodeRequest();
            qrCodeRequest.setPage("pages/card/index");
            qrCodeRequest.setScene(byPartnerAndMember.getId());
            String filePath = fileBizService.getUploadCIPath(byPartnerAndMember.getPartnerId(), "integral");
            String result = fileBizService.uploadCloudOut(byPartnerAndMember.getId(), filePath, qrCodeRequest, openMember.getAuthorizerAccessToken(), 1);
        } catch (Exception e) {
            logger.error("积分--生成个人资料小程序码异常", e.getMessage());
        }
        try {
            //生成推荐海报小程序码
            WechatOpenMember openMember = wechatOpenMemberService.findByType(Constant.WECHAT_ACCOUNT_TYPE_SYSTEM_XCX_INTEGRAL);
            XcxQrCodeRequest qrCodeRequest = new XcxQrCodeRequest();
            qrCodeRequest.setPage("pages/slogin/index");
            qrCodeRequest.setScene(byPartnerAndMember.getId());
            String filePath = fileBizService.getUploadCIPath(byPartnerAndMember.getPartnerId(), "integralRecommend");
            String result = fileBizService.uploadCloudOut(byPartnerAndMember.getId(), filePath, qrCodeRequest, openMember.getAuthorizerAccessToken(), 1);
        } catch (Exception e) {
            logger.error("积分--生成推荐海报小程序码异常", e.getMessage());
        }
    }

    /**
     * @Description:是否拥有行知公社权限
     * @Param:partnerId
     * @return:boolean
     * @Author: Hua Qunhao
     * @Date: 2019/11/22
     */
    public boolean isXZGSJurisdiction(String partnerId){
        boolean isCommune = false;
        try {
            Map<String, Object> stringObjectMap = Maps.newHashMap();
            stringObjectMap.put("type", RoleType.PARTNER_ROLE.getCode());
            stringObjectMap.put("memberId", partnerId);
            List<SysRole> sysRoles = sysRoleService.getRoleByMemberId(stringObjectMap);

            for (SysRole s : sysRoles) {
                if ("knowing_commune".equalsIgnoreCase(s.getCode())) {
                    isCommune = true;
                }
            }
        }catch (Exception e){
            logger.error("查询行知公社权限异常", e.getMessage());
        }
        return isCommune;
    }

    public ExportExcel setDataList(List<CUserIntegralMobileOutput> cUserIntegralMobileOutputs, ExportExcel exportExcel) {
        for (CUserIntegralMobileOutput output : cUserIntegralMobileOutputs) {
            Row row = exportExcel.addRow();
            String rank = output.getRanking().toString();
            String nickName = output.getName();
            String mobile = output.getMobile();
            String fraction = output.getFraction().toString();
            String partnerName = output.getPartnerName();

            CellStyle cellStyle = exportExcel.getWb().createCellStyle();
            exportExcel.addCell(row, 0, rank, cellStyle);
            exportExcel.addCell(row, 1, nickName, cellStyle);
            exportExcel.addCell(row, 2, mobile, cellStyle);
            exportExcel.addCell(row, 3, fraction, cellStyle);
            exportExcel.addCell(row, 4, partnerName, cellStyle);

        }

        return exportExcel;
    }

    public synchronized String getExcelPath(String fileName, String exportPath, ExportExcel exportExcel)
            throws IOException {
        String suffix = DateUtils.formatDate(new Date(), "yyyyMMddHHmmssSSS");
        if (fileName.indexOf(".xlsx") != -1) {
            fileName = fileName.substring(0, fileName.indexOf(".xlsx")) + '-' + suffix + ".xlsx";
        } else if (fileName.indexOf(".xls") != -1) {
            fileName = fileName.substring(0, fileName.indexOf(".xls")) + '-' + suffix + ".xls";
        }
        try {
            exportPath = String.format(uploadPath, exportPath, fileName);
            InputStream inputStream = exportExcel.newUploadCloud();
            UploadResult uploadResult = cosCloudBizService.uploadFile(inputStream, exportPath, InsertOnly.NO_OVER_WRITE);
            String resourceUrl = uploadResult.getSourceUrl();
            pushRedis(resourceUrl);
            return resourceUrl;
        } catch (Exception e) {
            logger.error("上传Excel到腾讯云异常：cloudFilePath——" + exportPath + "；cloudFileName——" + fileName, e);
        }
        return null;
    }
    public void pushRedis(String resourceUrl) {
        try {
            resourceUrl = URLDecoder.decode(resourceUrl, Constant.UTF_8);
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        List<Map> mapList = getRedisAll();
        Map<String, Object> map = Maps.newHashMap();
        map.put(resourceUrl, DateUtils.formatDate(new Date(), DateUtils.DATE_PATTERN));
        mapList.add(map);
        stringJedis.setValue(REDIS_LIST_KEY, JSONObject.toJSONString(mapList));
    }
    public List<Map> getRedisAll() {
        List<Map> mapList = Lists.newArrayList();
        String result = stringJedis.getValue(REDIS_LIST_KEY);
        if (StringUtils.isNotEmpty(result)) {
            mapList = JSONArray.parseArray(result, Map.class);
        }
        return mapList;
    }
}
